#ifndef SPINDLE_MOTOR_HPP
#define SPINDLE_MOTOR_HPP

#include <stdint.h>

class SpindleMotor{

public:
    class Adapter {
    public:
        virtual bool open(void) = 0;
        virtual bool close(void) = 0;
        virtual unsigned int read(void *buffer,unsigned int size) = 0;
        virtual unsigned int write(void *buffer,unsigned int size) = 0;
    };

public:
    virtual ~SpindleMotor();
    explicit SpindleMotor(Adapter *adapter);
    ////////////////////////////////////////// 数据处理 //////////////////////////////////////////
    virtual bool buildPackets(uint8_t RW,uint8_t slave_address , uint16_t access_address , uint16_t access_data); 
    virtual bool checkResponse(void);
    virtual uint16_t processResponse(void);
    
    ////////////////////////////////////////// 数据写入 //////////////////////////////////////////
    virtual bool open();                                        // RS485使能
    virtual bool close();                                       // RS485失能
    virtual bool addressSet(uint16_t address);                  // RS-485地址设定
    virtual bool setSpeed(uint16_t speed);                      // 设定电机转速
    virtual bool stopMotor();                                   // 电机停止
    virtual bool corotationMotor();                             // 电机正转
    virtual bool reversalMotor();                               // 电机反转
    virtual bool breakStop();                                   // 刹车停止
    virtual bool reductionSet(uint16_t reduction_ratio);        // 设定电机减速箱速比
    virtual bool resetFault(uint16_t reset_status);             // 复位故障
    virtual bool magneticSet(uint16_t pole);                    // 电机磁极对数设定
    virtual bool overcurrentProtectionTimeSet(uint16_t time);   // 过流保护时间设定

    ////////////////////////////////////////// 数据读取 //////////////////////////////////////////

    virtual uint16_t getSpeed(void);                            // 读取电机实际转速
    virtual uint16_t getMotorStatus(void);                      // 读取电机状态 0:停止 1:正转 2:反转 3:刹车
    virtual uint16_t getReduction();                            // 读取设定减速比
    virtual uint16_t getRestFault();                            // 读取报警代码
    virtual uint16_t getMagneticPairs();                        // 读取电机磁极设定值
    virtual uint16_t getOverCurrentProtectionTime();           // 读取电流保护设定时间
    virtual uint16_t getAddress();                              // 读取RS-485设定地址
    virtual uint16_t getStatus();                               // 读取RS-485状态
    virtual uint16_t getCurrentValue();                         // 读取电机实际电流值                
    virtual uint16_t getVoltageValue();                         // 读取供电电压值
    virtual uint16_t getTemperatue();                           // 读取控制器温度

    
    static SpindleMotor *getInstance();

protected:
    Adapter *adapter;

public:
    /* 从机地址 */
    typedef enum SlaveAddress{
        SlaveAddress_DefaultAddress = 0x01,
    }SlaveAddress_t;

    /* 功能码*/
    typedef enum FunctionCode{
        FunctionCode_WriteFun = 0x06,
        FunctionCode_ReadFun = 0x03,
    }FunctionCode_t;

    /* 寄存器地址 */
    typedef enum RegisterAddress{
        RegisterAddress_RS485Function = 0x00B6,              // 读写   RS-485 功能有效/无效
        RegisterAddress_RS485Address = 0x00A6,               // 读写   RS-485 地址设定
        RegisterAddress_MotorSpeed = 0x0056,                 // 读写   RS-485 设定电机转速
        RegisterAddress_MotorRotationControl = 0x0066,       // 读写   电机停止/正转/反转/刹车停止
        RegisterAddress_MotorReductionRatio = 0x0068,        // 读写   电机减速比
        RegisterAddress_ResetFault = 0x0076,                 // 读写   复位故障   0:正常 1:使能复位
        RegisterAddress_MagneticPoleSet = 0x0086,            // 读写   磁极对数设定
        RegisterAddress_OvercurrentProtectionSet = 0x0088,   // 读写   过流保护时间设定
        RegisterAddress_CurrentValue = 0x00C6,               // 只读   读取电机实际电流值
        RegisterAddress_VoltageValue = 0x00C8,               // 只读   读取电机供电电压值
        RegisterAddress_Temperature = 0x0096,                // 只读   读取控制器温度
    }RegisterAddress_t;

    /* 写入数据 */
    typedef enum Data{
        Data_0 = 0x0000,
        Data_1 = 0x0001,
        Data_2 = 0x0002,
        Data_3 = 0x0003,
    }Data_t;

    /* 读取响应数据错误类型 */
    typedef enum ResponseErrorType{
        ResponseErrorType_LengthError = 0xFFFF,       
        ResponseErrorType_AddressError = 0xFFFE,      
        ResponseErrorType_DataNumberError = 0xFFFD,
        ResponseErrorType_CRCError = 0xFFFC,
        ResponseErrorType_FunctionError = 0xFFFB,
        ResponseErrorType_DefaultError = 0xFFFA,
    }ResponseErrorType_t;

    /* 电机请求协议数据结构 */
    typedef struct RequestProtocol{
        uint8_t slave_address;      //  从机地址
        uint8_t function_code;      //  功能码
        uint16_t access_address;    //  访问地址
        uint16_t access_data;       //  访问数据
        uint16_t crc;               //  CRC校验
    }__attribute__((packed)) RequestProtocol_t;

    /* 电机应答协议数据结构 */
    typedef struct ResponseProtocol{
        uint8_t slave_address;      //  从机地址
        uint8_t function_code;      //  功能码
        uint8_t data_number;        //  数据个数
        uint16_t register_value;    //  从机寄存器值
        uint16_t crc;               //  CRC校验
    }__attribute__((packed)) ResponseProtocol_t;

};


#endif

